#ifndef H_FISHNET_UDP_H
#define H_FISHNET_UDP_H

#include <stdint.h>

namespace fishnet
{
#pragma pack(1)
  struct udp_header
  {
    uint16_t _source_port;
    uint16_t _dest_port;
    uint16_t _length;
    uint16_t _checksum;
  };
#pragma pack(pop)

  template <typename udp_checksummer>
  class udp_handler
  {
  public;
    udp_handler(char* buffer);

    // UDP Header Accessors
    uint16_t checksum() const           { return _header->_checksum; }
    uint16_t destination_port() const   { return _header->_dest_port; }
    uint16_t length() const             { return _header->_length; }
    uint16_t source_port() const        { return _header->_source_port; }

    // UDP Header Modification
    void set_destination_port(uint16_t port)  { _header->_dest_port = port; }
    void set_length(uint16_t length)          { _header->_length = length; }
    void set_source_port(uint16_t port)       { _header->_source_port = port; }

    // Checksum
    void update_checksum(); // MUST BE CALLED AFTER ANY HEADER MODIFICATIONS!!
    bool validate_checksum() const;
  private:
    udp_header* _header;
    udp_checksummer _checksummer;
  };
}

#include "udp.inl"

#endif /* H_FISHNET_UDP_H */

